/**********************************************************************************************/
/* FBL_I_Link_2.h		                                 	                   				  */
/*                                                                       					  */
/* Copyright Paradigma, 1993-2006															  */
/* All Rights Reserved                                                   					  */
/**********************************************************************************************/

#ifndef _FBL_I_Link2_h
	#define _FBL_I_Link2_h
#pragma once

// FBL:
#include <VShared/FBL/publ/Headers/FBL.h>

// FINAL:
#include <VShared/FBL/publ/Headers/FBL_pre_header.h>


/**********************************************************************************************/
FBL_Begin_Namespace


/**********************************************************************************************/
// forward declarations: 
//
SMART_INTERFACE(I_Table);

SMART_CLASS(ArraySet);
SMART_CLASS(BitSet);


/**********************************************************************************************/
// THIS module declarations:
//
SMART_INTERFACE(I_Link2);
 

/**********************************************************************************************/
// I_Link2 is an interface that provides abstraction of LINK between 2 tables of database.
//
//StubInterface
interface FBL_SHARED_EXP_CLASS I_Link2 :	public I_Unknown
{

virtual						~I_Link2();

	// ---------------------
	// Properties:

		// <LeftType> [r/o]
							/** Returns the relation type for the left branch. 
								Can be 1 (kOne) or M (kMany). */
virtual	LinkType			get_LeftType( void ) const throw()							= 0;

		// <RightType> [r/o]
							/** Returns the relation type for the left branch. 
								Can be 1 (kOne) or M (kMany). */
virtual	LinkType			get_RightType( void ) const throw()							= 0;


	// ---------------------
	// Record Methods:

							/** Links given records of 2 Tables */
virtual void				LinkRecords( REC_ID inLeft, REC_ID inRight )				= 0; 

							/** Unlinks given records of 2 Tables */
virtual void				UnlinkRecords( REC_ID inLeft, REC_ID inRight )				= 0; 

	// ---------------------
	// Methods to work with non-recursive link.

							/**	Returns the count of linked recods in the direction 
								1 -> Many. */
virtual	ulong				CountLinkedFrom1ToMany( REC_ID inRecID ) const				= 0;

							/**	Returns the count of linked recods in the direction 
								Many -> 1. */
virtual ulong				CountLinkedFromManyTo1( REC_ID inRecID ) const				= 0;

							/**	Returns the records from "One"-table linked to 
								inRecID from "Many"-table. If not have linked 
								returns NULL. */
virtual ArraySet_Ptr		FindLinkedFrom1ToMany( REC_ID inRecID ) const				= 0;

							/**	Returns the records from "Many"-table linked to 
								inRecID from "One"-table. If not have linked 
								returns NULL. */
virtual ArraySet_Ptr		FindLinkedFromManyTo1( REC_ID inRecID ) const				= 0;

							/**	Returns all the linked records from "Many"-table. */
virtual BitSet_Ptr			FindAllLinkedInManyTable( void ) const						= 0;

							/**	Returns all the linked records from "One"-table. */
virtual BitSet_Ptr			FindAllLinkedIn1Table( void ) const							= 0;


	// ---------------------
	// Methods to work with recursive link.

virtual	ulong				CountLinkedChildren( REC_ID inRecID ) const					= 0;
virtual ulong				CountLinkedParents( REC_ID inRecID ) const					= 0;

virtual ArraySet_Ptr		FindLinkedChildren( REC_ID inRecID ) const					= 0;
virtual ArraySet_Ptr		FindLinkedParents( REC_ID inRecID ) const					= 0;

virtual BitSet_Ptr			FindAllLinkedChildren( void ) const							= 0;
virtual BitSet_Ptr			FindAllLinkedParents( void ) const							= 0;


	// ---------------------
	// Helper methods.

							/**	Determines the type of link between two tables.
								Both tables must belong to this link otherwise
								result will be kInvalidLinkDirection. */
virtual ELinkDirection		DetectLinkDirection(
								Const_I_Table_Ptr inTableA, 
								Const_I_Table_Ptr inTableB ) const throw()				= 0;

							/**	Returns "One"-table if @inTable points to "Many"-table or
								returns "Many"-table if @inTable points to "One"-table or
								returns NULL otherwise. */
virtual	I_Table_Ptr			get_OppositeTable( Const_I_Table_Ptr inTable ) const throw() = 0;


							/** Copy "links" from source link to this one.
							*/
virtual	void				CopyLinksFrom( I_Link2_Ptr inpSourceLink ) = 0;

							/** This link must be M::M.
								Copy "links" from source links pair to this one.
							*/
virtual	void				CopyLinksFrom( 
								I_Link2_Ptr inpSourceLink1,
								I_Link2_Ptr inpSourceLink2 ) = 0;

							/** This link must be M::M.
								Copy this M::M "links" to target links pair.
							*/
virtual	void				CopyLinksTo( 
								I_Link2_Ptr inDestinationLink1,
								I_Link2_Ptr inDestinationLink2 ) = 0;

}; 


/**********************************************************************************************/
FBL_End_Namespace


/**********************************************************************************************/
#include <VShared/FBL/publ/Headers/FBL_post_header.h>


/**********************************************************************************************/
#endif // _FBL_I_Link2_h
